package com.example.event_resource_java.authority.server.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.event_resource_java.authority.dao.CourseClassDao.StuClassDO;
import com.example.event_resource_java.authority.dao.CourseClassDao.StudentClassesDO;
import com.example.event_resource_java.authority.mapper.ClassMapper;
import com.example.event_resource_java.authority.mapper.StatisticMapper;
import com.example.event_resource_java.authority.server.ClassService;
import com.example.event_resource_java.authority.server.UserServer;
import com.example.event_resource_java.commons.domain.UserDO;
import com.example.event_resource_java.commons.enums.Constants;
import com.example.event_resource_java.commons.enums.EnumErrorCode;
import com.example.event_resource_java.commons.util.*;
import com.example.event_resource_java.commons.vo.ClassPageResult;
import com.example.event_resource_java.commons.vo.ClassVO.StudentDetailVO;
import com.example.event_resource_java.commons.vo.PageResult;
import com.example.event_resource_java.commons.vo.ClassesVO;
import com.example.event_resource_java.commons.vo.ClassVO.StudentVO;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Date;
import java.util.List;

/**
 * @ClassName ClassServiceImpl
 * @Description: 班级管理
 * @Author: ak
 * @CreateDate: 2024/4/17 9:19
 * @UpdateUser:
 * @UpdateDate: 2024/4/17 9:19
 * @UpdateRemark:
 * @Version: 1.0
 */
@Service
public class ClassServiceImpl extends ServiceImpl<ClassMapper, StudentClassesDO>
        implements ClassService {

    @Resource
    private ClassMapper classMapper;

    @Resource
    private UserServer userServer;

    @Resource
    private StatisticMapper statisticMapper;

    /**
     * @auther: ak
     * @Description 添加单个学生/批量保存 班级学生关联表
     * @param:
     * @return:
     * @date: 2024/4/17 14:44
     */
    @Override
    public ApiResult batchSaveClass(String className, List<StudentVO> studentVOList) {
        String nowTime = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS);

        UserDO userDO = JWTUtil.getUser();
        UserDO teacherUserDO = userServer.getById(userDO.getId());

        StudentClassesDO studentClassesDO = new StudentClassesDO();
        studentClassesDO.setName(className);
        studentClassesDO.setCreaterDate(nowTime);
        studentClassesDO.setCreaterId(userDO.getId());
        studentClassesDO.setOrgId(userDO.getOrgId());
        studentClassesDO.setIsDelete(1);

        // 插入班级
        Long hasClassId = classMapper.getClassId(className, userDO.getId());
        if (hasClassId == null) {
            classMapper.insert(studentClassesDO);
        } else {
            // 存在被删除则恢复
            classMapper.reCreateClass(hasClassId, DateTime.now().toString());
        }
        Long classId = classMapper.getClassId(className, userDO.getId());

        for (StudentVO studentVO : studentVOList) {
            // 手机号重复判断
            QueryWrapper<UserDO> userDOQueryWrapper = new QueryWrapper<>();
            userDOQueryWrapper.eq("mobile", studentVO.getMobile());
            UserDO existUser = userServer.getOne(userDOQueryWrapper);
            if (ObjectUtil.isNotNull(existUser)) {
                StringBuffer sb = new StringBuffer();
                ApiResult<Object> apiResult = new ApiResult<>();
                apiResult.setCode(2);
                apiResult.setMsg(sb.append(studentVO.getName()).append("手机号已存在！").toString());
                return apiResult;
            }
        }

        UserDO user = new UserDO();
        // 密码 加盐
        user.setSalt(UUIDUtils.get());
        user.setPassword(PasswdUtils.get(Constants.DEFAULT_PASSWORD, user.getSalt()));
        user.setGmtCreate(nowTime);
        user.setUserIdCreate(userDO.getId());
        // 用户新增来源 1 金职资源库添加学生
        user.setUserFrom(1);
        // 0个人会员为学生 1机构会员为老师 2运营会员为讲师
        user.setType(Constants.SYS_USER_ROLE_STUDENT);

        // 添加学生到用户表
        for (StudentVO studentVO : studentVOList) {
            user.setName(studentVO.getName());
            user.setUsername(studentVO.getMobile());
            // 前端传输字段username == mobile
            user.setMobile(studentVO.getMobile());
            user.setSex(studentVO.getSex());
            // TODO 老师用户必须拥有省市区
            user.setProvince(teacherUserDO.getProvince());
            user.setCity(teacherUserDO.getCity());
            user.setDistrict(teacherUserDO.getDistrict());
            user.setOrgName(teacherUserDO.getOrgName());
            classMapper.saveUser(user);

            studentVO.setId(user.getId());
        }

        // 添加学生列表
        ArrayList<StuClassDO> stuClassDOList = new ArrayList<>();
        for (StudentVO studentVO : studentVOList) {

            StuClassDO stuClassDO = new StuClassDO();
            stuClassDO.setUserId(studentVO.getId());
            stuClassDO.setAddTime(nowTime);
            stuClassDO.setClassId(classId);
            stuClassDO.setExamineDate(nowTime);
            stuClassDO.setIsDelete(1);
            stuClassDO.setType(0);

            // 教师添加学生时 默认审核状态为已通过
            stuClassDO.setStatus(Constants.STUDENT_CLASS_STATUS_EXAMINATION_SUCCESS);
            stuClassDO.setDescribe(userDO.getName() + "用户添加的学生");
            stuClassDOList.add(stuClassDO);
        }

        ApiResult<Object> apiResult = new ApiResult<>();
        apiResult.setCode(0);
        // 只保存班级
        if (stuClassDOList.size() == 0) {
            apiResult.setMsg(EnumErrorCode.success.getMsg());
            return apiResult;
        }
        // 保存班级和学生
        boolean b = classMapper.batchSaveStuClass(stuClassDOList);
        if (b == true) {
            apiResult.setMsg(EnumErrorCode.success.getMsg());
        } else {
            apiResult.setMsg(EnumErrorCode.fail.getMsg());
        }
        return apiResult;
    }

    /**
     * @auther: ak
     * @Description 班级学生信息
     * @param:
     * @return:
     * @date: 2024/4/18 8:48
     */
    @Override
    public ClassPageResult getClassDetails(String name, String mobile, Long classId,
                                           Integer pageNum, Integer pageSize) {
        //获取回显班级名称
        String classname = classMapper.getClassById(classId);
        //分页
        PageHelper.startPage(pageNum, pageSize);
        List<StudentVO> classDetailList = classMapper.getStudentInfo(name, mobile, classId);
        PageInfo<StudentVO> pageInfo = new PageInfo<>(classDetailList);

        ArrayList<StudentDetailVO> studentDetailVOList = new ArrayList<>();
        if (ObjectUtil.isNotNull(pageInfo.getTotal())) {
            for (StudentVO studentVO : classDetailList) {
                StudentDetailVO studentDetailVO = new StudentDetailVO();
                BeanUtils.copyProperties(studentVO, studentDetailVO);
                studentDetailVO.setSex(studentVO.getSex().toString());
                studentDetailVOList.add(studentDetailVO);
            }
        }

        return new ClassPageResult(pageInfo.getTotal(), studentDetailVOList, classname);
    }

    /**
     * @auther: ak
     * @Description 删除学生
     * @param:
     * @return:
     * @date: 2024/4/19 16:15
     */
    @Override
    @Transactional
    public boolean quitStu(Long userId, Long classId) {
        // 删除学生
        userServer.removeById(userId);
        // 删除练习和学习记录
        statisticMapper.deletePracticeRecord(userId);
        statisticMapper.deleteLearnRecord(userId);
        return classMapper.quitStu(userId, classId);
    }

    /**
     * @auther: ak
     * @Description 更新班级信息
     * @param:
     * @return:
     * @date: 2024/4/19 16:16
     */
    @Override
    public boolean updateClass(Long classId, String className) {
        String nowTime = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD_HH_MM_SS);

        UserDO user = JWTUtil.getUser();
        Long updateId = user.getId();
        return classMapper.updateClass(classId, className, updateId, nowTime);
    }

    /**
     * @auther: ak
     * @Description 更新学生信息 或 重置密码密码
     * @param:
     * @return:
     * @date: 2024/4/19 16:17
     */
    @Override
    @Transactional
    public boolean updateStu(String name, String mobile, Integer sex, Long id, String password) {

        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String nowTime = dateFormat.format(date.getTime());

        UserDO oldUserDO = classMapper.getSysUserByUserId(id);

        // 传入密码不为空为修改密码请求
        if (StringUtils.isEmpty(name)) {
            name = oldUserDO.getName();
        }
        if (StringUtils.isEmpty(mobile)) {
            mobile = oldUserDO.getMobile();
        }
        if (sex == null) {
            sex = oldUserDO.getSex();
        }

        if (StringUtils.isEmpty(password)) {
            password = oldUserDO.getPassword();
        } else {
            String newPassword = new String(Base64.getDecoder().decode(password));
            // 生成新密码
            password = PasswdUtils.get(newPassword, oldUserDO.getSalt());
        }

        // 同时修改练习记录中的学生姓名
        statisticMapper.updatePracticeRecordInfo(oldUserDO.getId(), name);
        return classMapper.updateStu(name, mobile, sex, password, oldUserDO.getId(), nowTime);
    }

    /**
     * @auther: ak
     * @Description 获取班级列表
     * @param:
     * @return:
     * @date: 2024/4/19 16:17
     */

    @Override
    public PageResult list(String className, Integer pageNum, Integer pageSize) {

        UserDO user = JWTUtil.getUser();
        Long createrId = user.getId();

        // 获取班级
        PageHelper.startPage(pageNum, pageSize);
        List<ClassesVO> classList = classMapper.getClasses(className, createrId);

        for (ClassesVO classesVO : classList) {
            Long classId = classesVO.getId();
            Integer stuNum = classMapper.getStuNum(classId);
            classesVO.setStuNum(stuNum);
        }

        Page<ClassesVO> page = (Page<ClassesVO>) classList;
        return new PageResult(page.getTotal(), page.getResult());
    }

    /**
     * @auther: ak
     * @Description 禁止创建重名班级
     * @param:
     * @return:
     * @date: 2024/4/25 8:44
     */
    @Override
    public boolean isExistClass(String classname) {

        UserDO user = JWTUtil.getUser();
        Long createrId = user.getId();

        Long isExistClass = classMapper.isExistClass(classname, createrId);
        // 存在 返回true
        return isExistClass != null ? true : false;
    }

    /**
     * @auther: ak
     * @Description 获取班级列表
     * @param:
     * @return:
     * @date: 2024/4/25 11:11
     */
    @Override
    public List<String> classList() {
        UserDO user = JWTUtil.getUser();
        List<String> classList = classMapper.classList(user.getId());
        if (ObjectUtil.isNotNull(classList)) {
            return classList;
        }else {
            return null;
        }
    }

    /**
     * 删除班级
     *
     * @param classId
     * @return
     */
    @Override
    public boolean deleteClass(Long classId) {
        List<StuClassDO> stuClassList = classMapper.getStuClassById(classId);

        ArrayList<Long> idList = new ArrayList<>();
        if (ObjectUtil.isNotNull(stuClassList)) {
            for (StuClassDO stuClassDO : stuClassList) {
                if (stuClassDO.getIsDelete() == 1) {
                    // 物理删除用户
                    idList.add(stuClassDO.getUserId());
                    // 班级学生关联表也删除
                    classMapper.quitStu(stuClassDO.getUserId(), stuClassDO.getClassId());
                }
            }
            if (idList.size() != 0) {
                userServer.removeByIds(idList);
            }

        }

        return classMapper.deleteClass(classId);
    }
}
